﻿package com.logrogue.console.data {
	
	import com.logrogue.console.utils.createId;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;

	/**
	 * Описание приложения.
	 * 
	 * @version  1.0
	 * @author   meps
	 */
	public class CLogApplication extends EventDispatcher implements ILogApplication {
		
		/**
		 * Конструктор.
		 */
		public function CLogApplication() {
			m_modNames = [ ];
			m_modIds = [ ];
			m_modIndices = [ ];
			m_devNames = [ ];
			m_devIds = [ ];
			m_devIndices = [ ];
			m_logRecords = [ ];
			m_logIds = [ ];
			m_logIndices = [ ];
		}
		
		/**
		 * @inheritDoc
		 */
		public function get appID():String { return m_id; }
		
		/**
		 * @inheritDoc
		 */
		public function get appStart():Date {return m_start; }
		
		/**
		 * @inheritDoc
		 */
		public function get appName():String { return m_name; }
		
		/**
		 * @inheritDoc
		 */
		public function get appVersion():String { return m_version; }
		
		/**
		 * @inheritDoc
		 */
		public function get appBuild():int { return m_build; }
		
		public function appStart(start:Date = null, id:String = null, name:String = null, version:String = null, build:int = 0):void {
			if (start)
				m_start = start;
			else
				m_start = new Date();
			if (id)
				m_id = id;
			else
				m_id = createId();
			if (name)
				m_name = name;
			else
				m_name = NAME_DEFAULT;
			m_version = version;
			m_build = build;
		}
		
		///////////////////////////////////////////////////////////////////////
		
		/**
		 * @inheritDoc
		 */
		public function get modCount():int { return m_modNames.length; }
		
		/**
		 * @inheritDoc
		 */
		public function modNameAt(index:int):String {
			if (index < 0 || index >= m_modNames.length)
				return null;
			return m_modNames[index];
		}
		
		/**
		 * @inheritDoc
		 */
		public function modNameID(id:int):String {
			var i:int = m_modIds.indexOf(id);
			if (i < 0)
				return null;
			return m_modNames[m_modIndices[i]];
		}
		
		/**
		 * Добавить новый модуль.
		 * 
		 * @param   идентификатор;
		 * 
		 * @param   название модуля;
		 */
		public function modAdd(id:int, name:String):void {
			var i:int = m_modIds.indexOf(id);
			if (i < 0) {
				i = m_modIds.length;
				m_modIds[i] = id;
			}
			var j:int = m_modNames.indexOf(name);
			if (j < 0) {
				j = m_modNames.length;
				m_modNames[j] = name;
				m_modIndices[i] = j;
				dispatchEvent(new Event(EVENT_MODULE));
			} else {
				m_modIndices[i] = j;
			}
		}
		
		/**
		 * @inheritDoc
		 */
		public function get EVENT_MODULE():String { return "app:module"; }
		
		///////////////////////////////////////////////////////////////////////
		
		/**
		 * @inheritDoc
		 */
		public function get devCount():int { return m_developers.length; }
		
		/**
		 * @inheritDoc
		 */
		public function devNameAt(index:int):String {
			if (index < 0 || index >=  m_devNames.length)
				return null;
			return m_devNames[index];
		}

		/**
		 * @inheritDoc
		 */
		public function devNameID(id:int):String {
			var i:int = m_devIds.indexOf(id);
			if (i < 0)
				return null;
			return m_devNames[m_devIndices[i]];
		}
		
		/**
		 * Добавить разработчика.
		 * 
		 * @param   идентификатор;
		 * 
		 * @param   имя разработчика;
		 */
		public function devAdd(id:int, name:String):void {
			var i:int = m_devIds.indexOf(id);
			if (i < 0) {
				i = m_devIds.length;
				m_devIds[i] = id;
			}
			var j:int = m_devNames.indexOf(name);
			if (j < 0) {
				j = m_devNames.length;
				m_devNames[j] = name;
				m_devIndices[i] = j;
				dispatchEvent(new Event(EVENT_DEVELOPER));
			} else {
				m_devIndices[i] = j;
			}
		}

		/**
		 * @inheritDoc
		 */
		public function get EVENT_DEVELOPER():String { return "app:developer"; }
		
		///////////////////////////////////////////////////////////////////////
		
		/**
		 * @inheritDoc
		 */
		public function get logCount():int { return m_logRecords.length; }
		
		public function logRecordAt(index:int):ILogRecord {
			return null;
		}
		
		public function logRecordID(id:int):ILogRecord {
			return null;
		}
		
		public function logAdd(data:ILogRecord):void {
			// если время больше, чем время последней записи, то добавить в конец
			var l:int = m_logRecords.length;
			if (l == 0) {
				m_logRecords[l] = data;
			} else if ((m_logRecords[l - 1] as ILogRecord).time < data.time)
			
		}
		
		public function get EVENT_LOG():String { return "app:log"; }
		
		///////////////////////////////////////////////////////////////////////
		
		protected var m_id:String;
		protected var m_start:Date;
		protected var m_name:String;
		protected var m_version:String;
		protected var m_build:int;
		protected var m_modNames:Array /*String*/; // имена модулей
		protected var m_modIds:Array /*int*/; // идентификаторы модулей
		protected var m_modIndices:Array /*int*/; // соответствие идентификатора и индекса
		protected var m_devNames:Array /*String*/; // имена разработчиков
		protected var m_devIds:Array /*int*/; // идентификаторы разработчиков
		protected var m_devIndices:Array /*int*/; // соответствие идентификатора и индекса
		protected var m_logRecords:Array /*ILogRecord*/;
		protected var m_logIds:Array /*int*/;
		protected var m_logIndices:Array /*int*/;
		
		private static const NAME_DEFAULT:String = "default";
	}
	
}